在介紹過Servlet的運作與生命週期後,今日我們來看看層層繼承與實作當中在做什麼吧!
這一次我們有別於以往,我們繼承HttpServlet,並且按我們的需求override doGet方法
@WebServlet("/Hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.getWriter().println("Hello World!!!");
}
}
我們可以從intellij查看繼承結構,在HelloServlet右鍵選擇Show Diagram
選擇以method展開,頁面左上角m
我們先從最左邊的兩個interface分別是
作為tomcat可以再初始化Servlet傳遞設定檔訊息的物件
container會調用service方法處理http請求與回應,init方法則是第一次調用該servlet或是設定loadonstartup時調用一次的方法,destory則是該生命週期結束時會調用一次的方法
記得我們前幾天都是直接implement Servlet介面的實作範例,而這邊提供兩個抽象方法繼承替我們解決複雜的工,讓我們最後再繼承HttpServlet時只需要關注我們要處理的Http Method請求
關注service以外的方法與基礎處理
這邊實現了destroy空方法,讓我們下一個繼承的class有需要實現再override
init(ServletConfig config)幫我們把container傳遞給我們的配置訊息傳給成員變數,後面的繼承class可以方便調用,或透過getServletConfig()調用。
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
多了一個init()無參的空方法,並且在init(ServletConfig config)時會調用這個方法,目的在於後面的繼承class override這個init()時也可以被初始化
public void init() throws ServletException {}
@Override
public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
關注service的實現。此處將ServletRequest、ServletResponse轉成子物件HttpServletRequest、HttpServletResponse,代表container收到http請求時實際是封裝成HttpServletRequest、HttpServletResponse,所以此處轉型並不會有問題。最後將他們交由overloading的方法去執行,其中再依http method交由doXXX方法,後面繼承class按需實作欲處理的http method 的doXXX
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest && res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
若後面繼承的class為override doXXX則會被擋在父類調用getMethodNotSupportedCode回傳405
//以delete為例
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_delete_not_supported");
resp.sendError(getMethodNotSupportedCode(protocol), msg);
}
private int getMethodNotSupportedCode(String protocol) {
switch (protocol) {
case "HTTP/0.9":
case "HTTP/1.0":
return HttpServletResponse.SC_BAD_REQUEST;
default:
return HttpServletResponse.SC_METHOD_NOT_ALLOWED;
}
}